﻿using Microsoft.AspNetCore.Mvc;
using ParkSaleSDK.Adapter;
using ParkSaleSDK.Data;
using ParkSaleSDK.Modularity;
using ParkSaleSDK.QuickTool;
using ParkSalesRootAdapter;
using ReadOnlyParkSaleAdapter;
using System;
using System.Collections.Generic;
using SystemData;
using static ParkSaleSDK.MainSystem.MainSystem;
using static System.Console;
using static SystemSetting.Manangers;
using static SystemSetting.SystemAdapters;
namespace APIServer.Controllers
{
    [ApiController]
    [Route("[action]")]
    public class Controller : ControllerBase
    {
        static string GenerateSign(int location, int house, int number, string phone, string id)
        {
            return DataProcess.Encryption.RC4Encryption.RC4Encrypt_Base64($"{location}|{house}|{number}|{phone}|{id}", SignKey, System.Text.Encoding.UTF8);
        }
        static bool ReadFromSign(out User user, out OwnedHouse house, string sign)
        {
            sign = sign.Replace(' ', '+');
            user = new User();
            house = new OwnedHouse();
            try
            {
                string text = DataProcess.Encryption.RC4Encryption.RC4Decrypt_Base64(sign, SignKey, System.Text.Encoding.UTF8);

                string[] texts = text.Split('|');
                house.Location = int.Parse(texts[0]);
                house.House = int.Parse(texts[1]);
                house.Number = int.Parse(texts[2]);
                user.Phone = texts[3];
                user.ID = texts[4];
                return true;
            }
            catch (Exception ex)
            {
                WriteLine(ex.Message);
                return false;
            }


        }

        [HttpGet]
        public safe_User GetUser(string username)
        {
          var objs= r_User.Find<safe_User>(c_User.m_username, username);
            if (objs.Length > 0)
                return objs[0];
            else
                return null;
        }
        [HttpGet]
        public string Pay(int id)
        {
          Order[] orders=  r_Order.Find<Order>(c_Order.m_id, id.ToString());
           
            if (orders.Length > 0)
            {
                var p = r_Park.Find<Park>(c_Parking.m_id, orders[0].Number.ToString());
                if (p.Length > 0)
                {
                    if (p[0].Status == ParkPreOrdered && orders[0].Status == Order_NeedToPay)
                    {
                        w_Order.Update(orders[0], c_Order.k_Status, Order_Success.ToString());
                        w_Park.Update(p[0], c_Parking.k_Status, ParkSoldOut.ToString());
                        w_Rights.Append(new Rights() { Belong = orders[0].Belong, Item = p[0].ID });
                        return "订购成功";
                    }
                    else
                    {
                        return "订单错误，请检查订单和车位状态";
                    }
                }
                else
                {
                    return "无订单内容车位";
                }

            }
            return "订单不存在";
        }


        [HttpGet]
        public FullMessage[] RequestMessages(string id)
        {
            var arr = r_Message.Find<MessageData>(c_Message.m_to, id);
            List<FullMessage> msgs = new List<FullMessage>();
            foreach (var i in arr)
            {
                msgs.Add(i.ToFullMessage());
            }
            return msgs.ToArray();
        }

        [HttpGet]
        public Company[] FindCompanyByType(int type)
        {
            var r = r_Company.Find<Company>(c_Company.m_Type, type.ToString());
            return r;
        }
        [HttpGet]
        public Location[] FindLocation(int belong)
        {
            return r_location.Find<Location>(c_Location.m_Belong, belong.ToString());
        }

        [HttpGet]
        public Company FindCompanyByID(int id)
        {
            var r = r_Company.Find<Company>(c_Company.m_id, id.ToString());
            if (r.Length > 0)
                return r[0];
            else
                return null;
        }
        Random rand = new Random((int)DateTime.Now.Ticks);

        [HttpGet]
        public Advertisement[] RequestAD()
        {
            var r = r_AD.Find<Advertisement>(999);
            if (r.Length <= 5)
                return r;
            else
            {
                Advertisement[] ad = new Advertisement[5];
                for (int i = 0; i < 5; i++)
                {
                    int t = rand.Next(0, r.Length);
                    ad[i] = r[t];
                }
                return ad;
            }
        }

        [HttpGet]
        public FileContentResult ADImage(int id)
        {

            string path = ImageLocation + "\\" + id + ".jpg";
            string type = "image/jpeg";
            return new FileContentResult(System.IO.File.ReadAllBytes(path), type);
        }


        [HttpGet]
        public Park[] FindParks(int id)
        {
            return r_Park.Find<Park>(c_Parking.m_Location, id.ToString());
        }

        [HttpGet]
        public SurveyFeature[] SurveyFeatures()
        {
            List<SurveyFeature> ls = new List<SurveyFeature>();
            foreach (var i in Survey.AllValues())
            {
                ls.Add(new SurveyFeature() { Name = i.Name(), About = i.About() });
            }
            return ls.ToArray();
        }

        [HttpPost]
        public int ReplyMessage(int id, [FromBody] object args)
        {
            string ok = args.ToString();
            var arr = r_Message.Find<MessageData>(c_Message.m_id, id.ToString());
            if (arr.Length > 0)
            {
                if (arr[0].Handled > 0)
                    return -1;//消息已处理
                else
                {
                    var handle = Message[arr[0].Type];
                    if (handle != null)
                    {

                        try
                        {
                            int final = handle.HandleMessage(arr[0].ToFullMessage(), args);
                            if (final > 0)//消息处理结果>0时才处理成功
                                w_Message.Update(arr[0], c_Message.k_handled, "1");
                            return final;//消息处理结果
                        }
                        catch (Exception ex)
                        {
                            return -2;//信息处理时出错
                        }
                    }
                    else
                        return -3;//无效消息处理器
                }
            }
            else
                return 0;//无目标消息
        }
        [HttpGet]
        public PublicMessage[] Messages(string to)
        {
            var arr = r_Message.Find<MessageData>(c_Message.m_to, to);
            List<PublicMessage> ls = new List<PublicMessage>();
            foreach (var i in arr)
            {
                ls.Add(i.ToPublicMessage());
            }
            return ls.ToArray();
        }

        [HttpPost]
        public SurveyData SurveyRequest(string code, [FromBody] object args)
        {
            ISurvey survey = Survey[code];
            if (survey != null)
            {
                SurveyData data = null;
                switch (survey.WhatINeed())
                {
                    case DataNeedOption.Park:
                        data = survey.SurveyAction(r_Park, args);
                        break;
                    case DataNeedOption.Order:
                        data = survey.SurveyAction(r_Order, args);
                        break;
                    case DataNeedOption.Location:
                        data = survey.SurveyAction(r_location, args);
                        break;
                    case DataNeedOption.Company:
                        data = survey.SurveyAction(r_Company, args);
                        break;
                    case DataNeedOption.Ad:
                        data = survey.SurveyAction(r_AD, args);
                        break;
                    case DataNeedOption.User:
                        data = survey.SurveyAction(r_User, args);
                        break;
                    case DataNeedOption.Rights:
                        data = survey.SurveyAction(r_Rights, args);
                        break;
                    case DataNeedOption.UserOwnedHouse:
                        data = survey.SurveyAction(r_OwnedHouse, args);
                        break;
                }
                if (data != null)
                    return data;

            }
            return new SurveyData() { RequsetStatus = false, Result = "Error" };
        }

        [HttpPost]
        public int Register([FromBody] RegisterData data)
        {

            if (data.username.Length < 6 || data.password.Length < 8)
                return -1;
            data.password = DataProcess.Encryption.MD5Coder.MD5Encrypt(data.password, System.Text.Encoding.UTF8);
            User user;
            OwnedHouse owned;
            if (ReadFromSign(out user, out owned, data.sign))
            {
                try
                {
                    user.Password = data.password;
                    user.UserName = data.username;
                    if (wr_User.Find<User>(c_User.m_username, data.username).Length > 0)
                        return -2;
                    if (wr_User.Find<User>(c_User.m_id, data.id).Length > 0)
                        return -5;
                    if (owned.Location == data.location && owned.House == data.house && owned.Number == data.num && user.ID.Equals(data.id))
                    {
                        owned.Owner = user.ID;
                        wr_User.Append(user);
                        w_OwnedHouse.Append(owned);
                        return 1;
                    }
                    else
                        return -4;
                }
                catch
                {
                    return -3;
                }

            }
            return 0;

        }
        [HttpGet]
        public OutOrder Order(string id)
        {
            ReadableDatabaseAdapter adapter = r_Order;
            var result = adapter.Find<Order>(c_Order.m_id, id);
            OutOrder r = new OutOrder();
            if (result.Length > 0)
            {
                r.Basic = result[0];
                r.CompanyInfo = r_Company.Find<Company>(c_Company.m_id,result[0].Seller.ToString())[0];
                r.LocationInfo = r_location.Find<Location>(c_Location.m_id,result[0].Address.ToString())[0];
                return r;
            }

            else
                return null;
        }


        [HttpGet]
        public UserDiscount[] UseableDiscount(int order)
        {
            List<UserDiscount> ls = new List<UserDiscount>();
            var r = r_Order.Find<Order>(c_Order.m_id, order.ToString());
            if (r.Length > 0)
            {

                UserDiscount[] all = r_Discount.Find<UserDiscount>(c_Discount.m_Belong, r[0].Belong);
                Rights[] rights = r_Rights.Find<Rights>(c_Rights.m_belong, r[0].Belong);
                List<Park> hs = new List<Park>();
                foreach (var i in rights)
                {
                    var res = r_Park.Find<Park>(c_Parking.m_id, i.Item.ToString());
                    if (res.Length > 0)
                        hs.AddRange(res);
                }
                OwnedHouse[] houses = r_OwnedHouse.Find<OwnedHouse>(c_OwnedHouse.m_owner, r[0].Belong);

                foreach (var i in all)
                {
                    if (i.Order != null)
                        continue;
                    var ac = Dicount[i.Code];
                    if (ac != null)
                    {
                        if (ac.DiscountUseable(r[0], houses, hs.ToArray(), i.Arg))
                        {
                            ls.Add(i);
                        }
                    }
                }
                return ls.ToArray();

            }
            return ls.ToArray();
        }

        [HttpGet]
        public DiscountInfo[] myDiscount(string id)
        {
            List<DiscountInfo> ls = new List<DiscountInfo>();
            foreach (var i in r_Discount.Find<UserDiscount>(c_Discount.m_Belong, id))
            {

                ls.Add(new DiscountInfo(Dicount[i.Code]) { Discount = i });
            }
            return ls.ToArray();
        }

        [HttpGet]
        public int DiscountPick(string to, string code, string arg = null)
        {
            if (Dicount[code] == null)
                return -1;

            try
            {
                DateTime time = DateTime.Now;
                UserDicountAdapter adapter = w_Discount;
                adapter.Append(new UserDiscount() { PickTime = $"{time.Year}/{time.Month}/{time.Day} {time.Hour}:{time.Minute}:{time.Second}", Arg = arg != null ? arg : null, Belong = to, Code = code });
                return 1;
            }
            catch (Exception ex)
            {
                WriteLine(ex.Message);
                return 0;
            }

        }
        [HttpGet]
        public ParkingRights[] FindParkRightsByID(string id)
        {
            return ParkingRights.Find(id);
        }
        bool IsHadHouse(OwnedHouse[] house, int address)
        {
            foreach (var i in house)
            {
                if (i.Location == address)
                    return true;
            }
            return false;
        }
        [HttpPost]
        public Order UseDiscount(int order, int comfirm, [FromBody] PostableDiscount[] DiscountId)
        {
            Order[] orders = r_Order.Find<Order>(c_Order.m_id, order.ToString());
            if (orders.Length > 0)
            {
                var o = orders[0];
                List<UserDiscount> discounts = new List<UserDiscount>(UseableDiscount(order));
                Rights[] rights = r_Rights.Find<Rights>(c_Rights.m_belong, o.Belong);
                List<Park> hs = new List<Park>();
                foreach (var i in rights)
                {
                    var res = r_Park.Find<Park>(c_Parking.m_id, i.Item.ToString());
                    if (res.Length > 0)
                        hs.AddRange(res);
                }
                OwnedHouse[] houses = r_OwnedHouse.Find<OwnedHouse>(c_OwnedHouse.m_owner, o.Belong);
                foreach (var item in DiscountId)
                {
                    int id = item.id;
                    int index = discounts.FindIndex(delegate (UserDiscount d)
                    {
                        return d.ID == id;
                    });
                    if (index >= 0)
                    {
                        var now = discounts[index];
                        o.Price = Dicount[now.Code].FinalPrice(o, houses, hs.ToArray(), now.Arg);
                        if (comfirm == 1)
                        {
                            w_Discount.Update(now, c_Discount.k_Order, o.ID.ToString());
                            w_Order.Update(o, c_Order.k_Price, o.Price.ToString());
                        }
                    }
                }
                return o;
            }
            return null;
        }


        //PutOrder?buyer=330182199709230055&address=4&park=6&seller=8
        [HttpGet]
        public int PutOrder(string buyer, int address, int park, int? seller)
        {
            safe_UserTableAdapter userTableAdapter = r_User;
            readOnly_OwnedHouseAdapter house = r_OwnedHouse;
            var had = r_Order.Find<Order>(c_Order.m_Number, park.ToString());
            foreach (var i in had)
            {
                if (i.Belong.Equals(buyer) && i.Status != Order_Closed)
                    return -4;//已存在订单
            }
            var r = userTableAdapter.Find<User>(c_User.m_id, buyer);
            if (r.Length > 0)
            {
                var houses = house.Find<OwnedHouse>(c_OwnedHouse.m_owner, r[0].ID);
                if (houses.Length > 0)
                {
                    if (IsHadHouse(houses, address))
                    {
                        readOnly_ParkTableAdapter adapter = r_Park;
                        var p = adapter.Find<Park>(c_Parking.m_id, park.ToString());
                        if (p.Length > 0)
                        {
                            if (p[0].Location != address)
                            {
                                return -2;//指定小区无指定车位
                            }
                            if (p[0].Status != ParkOnSale)
                            {
                                return -3;//车位状态错误,不在在售状态下无法下单
                            }
                            int s;
                            if (seller == null)
                            {
                                var ls = r_location.Find<Location>(c_Location.m_id, address.ToString());
                                if (ls.Length > 0)
                                {
                                    s = ls[0].Belong;
                                }
                                else
                                    return -6;//小区信息错误
                            }
                            else
                            {
                                s = (int)seller;
                            }
                            Order o = new Order() { Belong = buyer, Status = Order_Pending, Seller =s, Address = address, Number = park, Price = p[0].Price, Time = Helper.TimeTOString(DateTime.Now) };
                            OrderAdapter orderad = w_Order;
                            orderad.Append(o);
                            return 1;//成功
                        }
                        else
                            return -1;//无指定ID的车位信息
                    }
                    else
                        return -4;//下单人无指定小区房产
                }

            }
            return -5;//下单人信息错误
        }
        //9Ofubmdl+Ik12l/wNWkrvCKoUwNNkxNtN1H/nG4leKR2RD++udMSqw==
        [HttpGet]
        public HouseInfo[] OwnedHouses(string user)
        {
            readOnly_OwnedHouseAdapter readOnly_OwnedHouseAdapter = r_OwnedHouse;
            List<HouseInfo> info = new List<HouseInfo>();
            foreach (var i in readOnly_OwnedHouseAdapter.Find<OwnedHouse>(c_OwnedHouse.m_owner, user))
            {
                HouseInfo house = new HouseInfo() { House = i };
                var ls = r_location.Find<Location>(c_Location.m_id, i.Location.ToString());
                if (ls.Length > 0)
                {
                    house.Location = ls[0];
                }
                info.Add(house);
            }
            return info.ToArray();
        }
        [HttpGet]
        public int RegisterHouseInfo(string sign, string user)
        {
            UserTableAdapter adapter = wr_User;
            OwnedHouseAdapter houseAdapter = w_OwnedHouse;
            User u;
            OwnedHouse house;
            if (ReadFromSign(out u, out house, sign))
            {
                var ur = adapter.Find<User>(c_User.m_id, user);
                if (ur.Length > 0)
                {
                    if (u.Phone.Equals(ur[0].Phone))
                    {
                        house.Owner = u.ID;
                        houseAdapter.Append(house);
                        return 1;
                    }
                    return -2;
                }
                return 0;
            }
            return -1;
        }

        [HttpGet]
        public OutOrder[] FindOrder(string id)
        {
            ReadableDatabaseAdapter adapter = r_Order;
            var orders= adapter.Find<Order>(c_Order.m_Belong, id);
            OutOrder[] results = new OutOrder[orders.Length];
            for (int i = 0; i < results.Length; i++)
            {
                results[i] = new OutOrder();
                results[i].Basic = orders[i];
                results[i].CompanyInfo = r_Company.Find<Company>(c_Company.m_id, orders[i].Seller.ToString())[0];
                results[i].LocationInfo =r_location.Find<Location>(c_Location.m_id, orders[i].Address.ToString())[0];
            }

            return results;
        }
        [HttpGet]
        public int Login(string username, string password)
        {
            UserTableAdapter adapter = wr_User;
            User[] result = adapter.Find<User>(c_User.m_username, username);
            if (result.Length > 0)
            {
                if (DataProcess.Encryption.MD5Coder.MD5Encrypt(password, System.Text.Encoding.UTF8).Equals(result[0].Password))
                    return 1;
                else
                    return 0;
            }
            else
                return -1;

        }
    }
}
